package com.camtc.camcenter.security;

import com.camtc.camcenter.util.BeanUtil;
import com.camtc.camcenter.util.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 保持登录操作
 * 借助Redis,进行用户登录状态的记录，默认记录7天
 *
 * @author
 * @date
 */

@Service("persistentRememberMeService")
public class PersistentRememberMeImpl implements PersistentTokenRepository {

    private final static String USERNAME_KEY = "spring:security:rememberMe:USERNAME_KEY:";
    private final static String SERIES_KEY = "spring:security:rememberMe:SERIES_KEY";

    private RedisUtils redisUtils;

    @Autowired
    public void setRedisUtils(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }

    @Override
    public void createNewToken(PersistentRememberMeToken token) {
        deleteIfPresent(token.getUsername());
        Map<String, Object> tokenMap = BeanUtil.convertBeanMap(PersistentRememberMeToken.class, token);
        redisUtils.hmSet(generateKey(token.getSeries(), SERIES_KEY), tokenMap);
        redisUtils.expireKey(generateKey(token.getSeries(), SERIES_KEY), 7L, TimeUnit.DAYS);
        redisUtils.set(generateKey(token.getUsername(), USERNAME_KEY), token.getSeries(), 7L, TimeUnit.DAYS);
    }

    @Override
    public void updateToken(String series, String tokenValue, Date lastUsed) {
        String key = generateKey(series, SERIES_KEY);
        if (redisUtils.exists(key)) {
            redisUtils.hmSet(key, "token", tokenValue);
        }
    }

    @Override
    public PersistentRememberMeToken getTokenForSeries(String seriesId) {
        String key = generateKey(seriesId, SERIES_KEY);
        Map<String, Object> data = redisUtils.hmGetAll(key, BeanUtil.beanKeys(PersistentRememberMeToken.class));
        PersistentRememberMeToken token = BeanUtil.convertMapBean(data, PersistentRememberMeToken.class);
        return token;
    }

    @Override
    public void removeUserTokens(String username) {
        String key = generateKey(username, USERNAME_KEY);
        deleteIfPresent(key);
    }

    /**
     * 删除键
     *
     * @param key
     */
    private void deleteIfPresent(String key) {
        if (redisUtils.exists(key)) {
            String series = generateKey(redisUtils.get(key).get(), SERIES_KEY);
            if (series != null && redisUtils.exists(series)) {
                redisUtils.remove(series);
                redisUtils.remove(key);
            }
        }
    }

    /**
     * 生成对应KEY值
     *
     * @param series
     * @param prefix
     * @return
     */
    private String generateKey(String series, String prefix) {
        return prefix + series;
    }
}
